package com.zero.basic.dao;

import java.lang.reflect.ParameterizedType;
import java.util.Collection;
import java.util.Map;
import java.util.Set;

import javax.inject.Inject;

import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;

import com.zero.basic.model.Pager;
import com.zero.basic.model.SystemContext;
import com.zero.basic.util.BlogConstants;

public abstract class DefaultBaseDao<T> implements IBaseDao<T> {

	@Inject
	private SessionFactory sessionFactory;
	private Class<?> clz;

	protected Class<?> getClz() {
		if (clz == null) {
			clz = ((Class<?>) (((ParameterizedType) (this.getClass()
					.getGenericSuperclass())).getActualTypeArguments()[0]));
		}
		return clz;
	}

	protected Session getSession() {
		return sessionFactory.getCurrentSession();
	}

	public T add(T t) {
		getSession().save(t);
		getSession().flush();
		return t;
	}

	public void update(T t) {
		getSession().update(t);
		getSession().flush();
	}

	public void delete(T t) {
		getSession().delete(t);
		getSession().flush();
	}

	public void delete(int id) {
		getSession().delete(this.load(id));
		getSession().flush();
	}

	@SuppressWarnings("unchecked")
	public T load(int id) {
		return (T) getSession().load(getClz(), id);
	}

	protected String initSort(String hql) {
		String order = SystemContext.getOrder();
		String sort = SystemContext.getSort();
		if (sort != null && !"".equals(sort.trim())) {
			hql += " order by " + sort;
			if (!"desc".equals(order))
				hql += " asc";
			else
				hql += " desc";
		}
		return hql;
	}

	@SuppressWarnings("rawtypes")
	protected void setAliasParameter(Query query, Map<String, Object> alias) {
		if (alias != null) {
			Set<String> keys = alias.keySet();
			for (String key : keys) {
				Object val = alias.get(key);
				if (val instanceof Collection) {
					// 查询条件是列表
					query.setParameterList(key, (Collection) val);
				} else {
					query.setParameter(key, val);
				}
			}
		}
	}

	protected void setParameter(Query query, Object[] args) {
		if (args != null && args.length > 0) {
			int index = 0;
			for (Object arg : args) {
				query.setParameter(index++, arg);
			}
		}
	}

	protected void setPagers(Query query, Pager<?> pages) {
		Integer pageSize = SystemContext.getPageSize();
		Integer pageOffset = SystemContext.getPageOffset();
		if (pageOffset == null || pageOffset < 0)
			pageOffset = BlogConstants.DEFAULT_PAGE_OFFSET;
		if (pageSize == null || pageSize < 0)
			pageSize = BlogConstants.DEFAULT_PAGE_SIZE;
		pages.setOffset(pageOffset);
		pages.setSize(pageSize);
		query.setFirstResult(pageOffset).setMaxResults(pageSize);
	}

	protected String getCountHql(String hql, boolean isHql) {
		String e = hql.substring(hql.indexOf("from"));
		String c = "select count(*) " + e;
		if (isHql)
			c = c.replaceAll("fetch", "");
		return c;
	}
}
